package com.adk.backend.service.impl;

import com.adk.backend.entity.LxCDelivery;
import com.adk.backend.entity.LxBillingList;
import com.adk.backend.entity.LxBillingDetails;
import com.adk.backend.mapper.CDeliveryMapper;
import com.adk.backend.mapper.BillingListMapper;
import com.adk.backend.mapper.BillingDetailsMapper;
import com.adk.backend.mapper.FeeTypeMapper;
import com.adk.backend.mapper.UnitListMapper;
import com.adk.backend.entity.LxFeeType;
import com.adk.backend.entity.LxUnitList;
import com.adk.backend.service.CDeliveryService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 派送单管理服务实现类
 */
@Slf4j
@Service
public class CDeliveryServiceImpl implements CDeliveryService {
    
    @Autowired
    private CDeliveryMapper deliveryMapper;
    
    @Autowired
    private BillingListMapper billingListMapper;
    
    @Autowired
    private BillingDetailsMapper billingDetailsMapper;
    
    @Autowired
    private FeeTypeMapper feeTypeMapper;
    
    @Autowired
    private UnitListMapper unitListMapper;
    
    @Override
    public List<Map<String, Object>> getDeliveryList(Map<String, Object> params) {
        return deliveryMapper.selectDeliveryListWithCustomerAndBilling(params);
    }
    
    @Override
    public Map<String, Object> getDeliveryDetailById(Long id) {
        return deliveryMapper.selectDeliveryDetailById(id);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveDelivery(LxCDelivery delivery) {
        try {
            // 处理预约日期时间戳
            if (delivery.getBookingDate() != null && !delivery.getBookingDate().isEmpty()) {
                try {
                    LocalDate date = LocalDate.parse(delivery.getBookingDate(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                    delivery.setBookingDateInt((int) (date.atStartOfDay().atZone(java.time.ZoneId.systemDefault()).toEpochSecond()));
                } catch (Exception e) {
                    log.warn("日期格式转换失败: {}", delivery.getBookingDate(), e);
                }
            }
            
            if (delivery.getId() != null && delivery.getId() > 0) {
                // 更新
                deliveryMapper.updateById(delivery);
            } else {
                // 新增
                deliveryMapper.insert(delivery);
            }
            return true;
        } catch (Exception e) {
            log.error("保存派送单失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteDelivery(Long id) {
        try {
            deliveryMapper.deleteById(id);
            return true;
        } catch (Exception e) {
            log.error("删除派送单失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateRemarks(Long id, String remarks, Integer userId) {
        try {
            LxCDelivery delivery = deliveryMapper.selectById(id);
            if (delivery == null) {
                return false;
            }
            
            delivery.setRemarks(remarks);
            delivery.setUpdateUid(userId);
            delivery.setUpdateTime((int) (System.currentTimeMillis() / 1000));
            
            deliveryMapper.updateById(delivery);
            return true;
        } catch (Exception e) {
            log.error("更新备注失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateBookingDate(Long id, String bookingDate, Integer userId) {
        try {
            LxCDelivery delivery = deliveryMapper.selectById(id);
            if (delivery == null) {
                return false;
            }
            
            if (bookingDate != null && !bookingDate.isEmpty()) {
                delivery.setBookingDate(bookingDate);
                try {
                    LocalDate date = LocalDate.parse(bookingDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                    delivery.setBookingDateInt((int) (date.atStartOfDay().atZone(java.time.ZoneId.systemDefault()).toEpochSecond()));
                } catch (Exception e) {
                    log.warn("日期格式转换失败: {}", bookingDate, e);
                }
            } else {
                delivery.setBookingDate("");
                delivery.setBookingDateInt(0);
            }
            
            delivery.setUpdateUid(userId);
            delivery.setUpdateTime((int) (System.currentTimeMillis() / 1000));
            
            deliveryMapper.updateById(delivery);
            return true;
        } catch (Exception e) {
            log.error("更新预约日期失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateRecvInfo(Long id, Integer recvType, String recvNo, String recvDate, String pod, Integer userId) {
        try {
            LxCDelivery delivery = deliveryMapper.selectById(id);
            if (delivery == null) {
                return false;
            }
            
            delivery.setRecvType(recvType);
            delivery.setRecvNo(recvNo);
            delivery.setRecvDate(recvDate);
            if (recvDate != null && !recvDate.isEmpty()) {
                try {
                    LocalDate date = LocalDate.parse(recvDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                    delivery.setRecvTime((int) (date.atStartOfDay().atZone(java.time.ZoneId.systemDefault()).toEpochSecond()));
                } catch (Exception e) {
                    log.warn("日期格式转换失败: {}", recvDate, e);
                }
            }
            delivery.setRecvUid(userId);
            delivery.setRecvd(2); // 已签收
            delivery.setPod(pod);
            
            deliveryMapper.updateById(delivery);
            return true;
        } catch (Exception e) {
            log.error("更新签收信息失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean markReceivable(Long id) {
        try {
            LxCDelivery delivery = deliveryMapper.selectById(id);
            if (delivery == null || delivery.getBillingId() == null || delivery.getBillingId() == 0) {
                return false;
            }
            
            delivery.setIsReceivable(1);
            deliveryMapper.updateById(delivery);
            
            // 同时更新账单表的is_receivable字段
            if (delivery.getBillingId() != null && delivery.getBillingId() > 0) {
                LxBillingList billing = billingListMapper.selectById(delivery.getBillingId());
                if (billing != null) {
                    billing.setIsReceivable(1);
                    billingListMapper.updateById(billing);
                }
            }
            return true;
        } catch (Exception e) {
            log.error("标记应收失败", e);
            return false;
        }
    }
    
    @Override
    public Map<String, Object> getBillingInfo(Long deliveryId) {
        Map<String, Object> result = new HashMap<>();
        
        // 查询派送单账单信息
        Map<String, Object> billingInfo = deliveryMapper.selectBillingInfo(deliveryId);
        if (billingInfo == null) {
            return result;
        }
        
        result.put("deliveryInfo", billingInfo);
        
        // 查询账单明细
        Long billingId = billingInfo.get("billing_id") != null ? 
            Long.valueOf(billingInfo.get("billing_id").toString()) : null;
        
        List<Map<String, Object>> details = new ArrayList<>();
        if (billingId != null && billingId > 0) {
            List<LxBillingDetails> billingDetails = billingDetailsMapper.selectByBillId(billingId);
            for (LxBillingDetails detail : billingDetails) {
                Map<String, Object> detailMap = new HashMap<>();
                detailMap.put("id", detail.getId());
                detailMap.put("feeType", detail.getFeeType());
                detailMap.put("shipWeigthNum", detail.getShipWeigthNum());
                detailMap.put("price", detail.getPrice());
                detailMap.put("currencyId", detail.getCurrencyId());
                detailMap.put("unitId", detail.getUnitId());
                detailMap.put("exchangeRateSar", detail.getExchangeRateSar());
                detailMap.put("exchangeRate", detail.getExchangeRateSar()); // 用于前端显示
                
                // 查询费用类型名称
                if (detail.getFeeType() != null) {
                    LxFeeType feeType = feeTypeMapper.selectById(detail.getFeeType());
                    if (feeType != null) {
                        detailMap.put("feeName", feeType.getFeeName());
                    }
                }
                
                // 查询单位名称
                if (detail.getUnitId() != null) {
                    LxUnitList unit = unitListMapper.selectById(detail.getUnitId());
                    if (unit != null) {
                        detailMap.put("unitName", unit.getUnitName());
                    }
                }
                
                details.add(detailMap);
            }
        }
        result.put("details", details);
        
        // 查询费用类型列表（type=3，用于派送账单）
        QueryWrapper<LxFeeType> feeTypeWrapper = new QueryWrapper<>();
        feeTypeWrapper.eq("type", 3).orderByAsc("id");
        List<LxFeeType> feeTypes = feeTypeMapper.selectList(feeTypeWrapper);
        result.put("feeTypes", feeTypes);
        
        // 查询单位列表
        List<LxUnitList> units = unitListMapper.selectList(new QueryWrapper<>());
        result.put("units", units);
        
        return result;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveBilling(Long deliveryId, Map<String, Object> billingData, Integer userId) {
        try {
            // 获取派送单信息
            LxCDelivery delivery = deliveryMapper.selectById(deliveryId);
            if (delivery == null) {
                throw new RuntimeException("派送单不存在");
            }
            
            // 检查预约日期
            if (delivery.getBookingDateInt() == null || delivery.getBookingDateInt() <= 0) {
                throw new RuntimeException("错误,没有预约时间无法出账单");
            }
            
            // 检查是否已创建账单
            QueryWrapper<LxBillingList> wrapper = new QueryWrapper<>();
            wrapper.eq("order_id", deliveryId).eq("ship_type", 5);
            LxBillingList existingBill = billingListMapper.selectOne(wrapper);
            
            Long billingId;
            boolean isNew = (existingBill == null);
            
            if (isNew) {
                // 创建新账单
                LxBillingList billing = new LxBillingList();
                billing.setOrderId(deliveryId);
                billing.setCustomerId(delivery.getCustomerId());
                billing.setTotalCtns(delivery.getTotalCtns());
                billing.setCurrencyId(1); // RMB
                billing.setShipType(5); // 派送账单
                billing.setBillDate(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
                billing.setBillDateInt((long) (System.currentTimeMillis() / 1000));
                billing.setRecvTime(delivery.getBookingDateInt());
                billing.setAddUid((long) userId);
                billing.setAddTime((int) (System.currentTimeMillis() / 1000));
                billing.setExchangeRateSar(((BigDecimal) billingData.getOrDefault("exchangeRateSar", BigDecimal.ONE)));
                billing.setExchangeRateUsd(((BigDecimal) billingData.getOrDefault("exchangeRateUsd", BigDecimal.ONE)));
                billing.setRemarks((String) billingData.getOrDefault("billRemarks", ""));
                billing.setIsReceivable(1);
                
                billingListMapper.insert(billing);
                billingId = billing.getId();
                
                // 更新派送单
                delivery.setBillingId(billingId);
                delivery.setIsBill(1);
                delivery.setEditBillUid(userId);
                delivery.setEditBillTime((int) (System.currentTimeMillis() / 1000));
                delivery.setIsReceivable(1);
                deliveryMapper.updateById(delivery);
            } else {
                billingId = existingBill.getId();
                
                // 检查是否已付款（需要授权码，这里简化处理）
                if (existingBill.getPaid() != null && existingBill.getPaid() == 1) {
                    // 如果需要授权码验证，可以在这里添加
                }
                
                // 更新账单
                existingBill.setUpdateUid(userId);
                existingBill.setUpdateTime((int) (System.currentTimeMillis() / 1000));
                existingBill.setExchangeRateSar(((BigDecimal) billingData.getOrDefault("exchangeRateSar", BigDecimal.ONE)));
                existingBill.setExchangeRateUsd(((BigDecimal) billingData.getOrDefault("exchangeRateUsd", BigDecimal.ONE)));
                existingBill.setRemarks((String) billingData.getOrDefault("billRemarks", ""));
                existingBill.setIsReceivable(1);
                billingListMapper.updateById(existingBill);
                
                // 更新派送单
                delivery.setEditBillUid(userId);
                delivery.setEditBillTime((int) (System.currentTimeMillis() / 1000));
                deliveryMapper.updateById(delivery);
            }
            
            // 处理账单明细
            @SuppressWarnings("unchecked")
            List<Map<String, Object>> details = (List<Map<String, Object>>) billingData.get("details");
            if (details != null) {
                BigDecimal totalAmount = BigDecimal.ZERO;
                
                for (Map<String, Object> detail : details) {
                    Long detailId = detail.get("id") != null ? 
                        Long.valueOf(detail.get("id").toString()) : null;
                    
                    Integer feeType = Integer.valueOf(detail.get("feeType").toString());
                    BigDecimal shipWeigthNum = new BigDecimal(detail.get("shipWeigthNum").toString());
                    BigDecimal price = new BigDecimal(detail.get("price").toString());
                    Integer currencyId = Integer.valueOf(detail.get("currencyId").toString());
                    Integer unitId = detail.get("unitId") != null ? 
                        Integer.valueOf(detail.get("unitId").toString()) : null;
                    BigDecimal exchangeRate = new BigDecimal(detail.getOrDefault("exchangeRate", "1").toString());
                    
                    if (detailId != null && detailId > 0) {
                        // 更新
                        LxBillingDetails billingDetail = billingDetailsMapper.selectById(detailId);
                        if (billingDetail != null) {
                            billingDetail.setPrice(price);
                            billingDetail.setShipWeigthNum(shipWeigthNum);
                            billingDetail.setExchangeRateSar(exchangeRate);
                            billingDetailsMapper.updateById(billingDetail);
                        }
                    } else {
                        // 新增
                        LxBillingDetails billingDetail = new LxBillingDetails();
                        billingDetail.setBillId(billingId);
                        billingDetail.setOrderId(deliveryId);
                        billingDetail.setFeeType(feeType);
                        billingDetail.setShipWeigthNum(shipWeigthNum);
                        billingDetail.setPrice(price);
                        billingDetail.setCurrencyId(currencyId);
                        billingDetail.setUnitId(unitId);
                        billingDetail.setExchangeRateSar(exchangeRate);
                        billingDetail.setExchangeRateUsd(exchangeRate);
                        billingDetail.setShipType(5);
                        billingDetailsMapper.insert(billingDetail);
                    }
                    
                    // 计算总金额
                    if (currencyId == 1) {
                        // RMB
                        totalAmount = totalAmount.add(price.multiply(shipWeigthNum));
                    } else {
                        // 其他货币，需要乘以汇率
                        totalAmount = totalAmount.add(price.multiply(shipWeigthNum).multiply(exchangeRate));
                    }
                }
                
                // 更新账单总金额
                existingBill = billingListMapper.selectById(billingId);
                if (existingBill != null) {
                    existingBill.setTotalAmount(totalAmount);
                    billingListMapper.updateById(existingBill);
                }
                
                // 更新派送单账单金额
                delivery.setBillingAmount(totalAmount);
                deliveryMapper.updateById(delivery);
            }
            
            return true;
        } catch (Exception e) {
            log.error("保存账单失败", e);
            throw new RuntimeException("保存账单失败：" + e.getMessage());
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteBillingDetailItem(Long detailId) {
        try {
            LxBillingDetails detail = billingDetailsMapper.selectById(detailId);
            if (detail == null) {
                return false;
            }
            
            Long billId = detail.getBillId();
            Long orderId = detail.getOrderId();
            
            // 删除明细项
            billingDetailsMapper.deleteById(detailId);
            
            // 重新计算账单总金额
            QueryWrapper<LxBillingDetails> wrapper = new QueryWrapper<>();
            wrapper.eq("bill_id", billId);
            List<LxBillingDetails> details = billingDetailsMapper.selectList(wrapper);
            
            BigDecimal totalAmount = BigDecimal.ZERO;
            for (LxBillingDetails d : details) {
                if (d.getCurrencyId() == 1) {
                    totalAmount = totalAmount.add(d.getPrice().multiply(d.getShipWeigthNum()));
                } else {
                    totalAmount = totalAmount.add(d.getPrice().multiply(d.getShipWeigthNum()).multiply(d.getExchangeRateSar()));
                }
            }
            
            // 更新账单总金额
            LxBillingList billing = billingListMapper.selectById(billId);
            if (billing != null) {
                billing.setTotalAmount(totalAmount);
                billingListMapper.updateById(billing);
            }
            
            // 更新派送单账单金额
            LxCDelivery delivery = deliveryMapper.selectById(orderId);
            if (delivery != null) {
                delivery.setBillingAmount(totalAmount);
                deliveryMapper.updateById(delivery);
            }
            
            return true;
        } catch (Exception e) {
            log.error("删除账单明细项失败", e);
            return false;
        }
    }
}

